#include "esVariableViewer.h"
#include "easyShell.h"

typedef struct {
    uint8_t showName[ES_VARIABLE_NAME_MAX+1];
    uint8_t varType;
    void* var;
    uint8_t tableCellWidth;
    uint8_t decHex;
} variableTypedef;

static variableTypedef shellVar[ES_VARIABLE_MAX];

int esVarLoop(int argc, char** argv);

void esVarInit(void)
{
    shellCmdTypedef varCmdInfo={
        .pName="var",
#if ES_CMD_BRIEF_ENABLE == 1
        .pBrief="variable view",
#endif
        .pFunc=esVarLoop,
    };
    easyShellAddCmd(varCmdInfo);
    for(uint8_t i=0; i<ES_VARIABLE_MAX; i++)
    {
        shellVar[i].showName[0]=0;
    }
}

void easyShellPrintVariable(uint8_t varType,void* var,uint8_t width,uint8_t decHex)
{
    int32_t *i32Temp;
    float *dTemp;
    uint8_t tempBuf[64]= {0};
    uint8_t sprintfCmd[8]="%16d";
    switch(varType)
    {
    case VAR_TYPE_INT_32:
    {
        i32Temp=var;
        if(decHex==10)
        {
            sprintf((char*)sprintfCmd,"%%-%dd",width);
        }
        else
        {
            sprintf((char*)sprintfCmd,"0x%%-%dX",width-2);
        }
        sprintf((char*)tempBuf,(const char*)sprintfCmd,*i32Temp);
        break;
    }
    case VAR_TYPE_FLOAT:
    {
        dTemp=var;
        sprintf((char*)sprintfCmd,"%%-%df",width);
        sprintf((char*)tempBuf,(const char*)sprintfCmd,*dTemp);
        break;
    }
    default:
        break;
    }
    esSysInfo.sendFunc(tempBuf,strlen((const char*)tempBuf));
}

#define FLOAT_WIDTH       12
#define INT32_DEC_WIDTH   10
#define INT32_HEX_WIDTH   6

void esVarAdd(uint8_t num,uint8_t* showName,uint8_t varType,void* var,uint8_t decHex)
{
    uint8_t nameLen;
    if(num<ES_VARIABLE_MAX)
    {
        nameLen=strlen((const char*)showName);
        nameLen=(ES_VARIABLE_NAME_MAX<nameLen)?ES_VARIABLE_NAME_MAX:nameLen;

        memcpy(shellVar[num].showName,showName,nameLen);
        shellVar[num].varType=varType;
        shellVar[num].var=var;
        if(varType==VAR_TYPE_INT_32)
        {
            if(decHex==10)
            {
                shellVar[num].decHex=10;
                shellVar[num].tableCellWidth=INT32_DEC_WIDTH;
            }
            else
            {
                shellVar[num].decHex=16;
                shellVar[num].tableCellWidth=INT32_HEX_WIDTH;
            }
        }
        else
        {
            shellVar[num].decHex=10;
            shellVar[num].tableCellWidth=FLOAT_WIDTH;
        }
    }
}
uint16_t esVarTickCount=0;
#define MAX(a,b)  (((a)>(b))?(a):(b))
void esVarTick(uint8_t cycleMs)
{
    uint8_t tableCellWidth;

    esVarTickCount++;
    if(esVarTickCount>=(1000/cycleMs))
    {
        esSysInfo.sendFunc((uint8_t*)"\r",1);

        for(uint8_t i=0; i<ES_VARIABLE_MAX; i++)
        {
            if(shellVar[i].showName[0]!=0)
            {
                tableCellWidth=MAX(ES_VARIABLE_NAME_MAX,shellVar[i].tableCellWidth);
                easyShellPrintVariable(shellVar[i].varType,shellVar[i].var,tableCellWidth,shellVar[i].decHex);
            }
        }
    }
}

int esVarLoop(int argc, char** argv)
{
    uint8_t i,j;
    uint8_t tableCellWidth;
    uint8_t buf=0x5F;
    
    esSysInfo.tickFunc=esVarTick;
    esSysInfo.isExit=false;

    for(i=0; i<ES_VARIABLE_MAX; i++)
    {
        if(shellVar[i].showName[0]!=0)
        {
            tableCellWidth=MAX(ES_VARIABLE_NAME_MAX,shellVar[i].tableCellWidth);
            for(j=0; j<tableCellWidth; j++)
            {
                esSysInfo.sendFunc(&buf,1);
            }
        }
    }
    esSysInfo.sendFunc((uint8_t*)"\r\n",2);

    for(i=0; i<ES_VARIABLE_MAX; i++)
    {
        if(shellVar[i].showName[0]!=0)
        {
            tableCellWidth=MAX(ES_VARIABLE_NAME_MAX,shellVar[i].tableCellWidth);
            esSysInfo.sendFunc(shellVar[i].showName,strlen((const char*)shellVar[i].showName));
            for(j=strlen((const char*)shellVar[i].showName); j<tableCellWidth; j++)
            {
                esSysInfo.sendFunc((uint8_t*)" ",1);
            }
        }
    }
    esSysInfo.sendFunc((uint8_t*)"\r\n",2);
    return 0;
}
